package com.example.config;

import com.example.filter.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; // ✅ 新增导入
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * 配置类，用于设置Web安全和方法级别的安全性
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    // JWT身份验证过滤器
    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    // 用户详细服务，使用Lazy注解延迟加载以避免循环依赖
    private final UserDetailsService userDetailsService;

    /**
     * 构造函数注入JWT身份验证过滤器和用户详细服务
     *
     * @param jwtAuthenticationFilter JWT身份验证过滤器
     * @param userDetailsService 用户详细服务，使用Lazy注解延迟加载
     */
    public SecurityConfig(
            JwtAuthenticationFilter jwtAuthenticationFilter,
            @Lazy UserDetailsService userDetailsService) { // 🔁 使用 @Lazy 延迟加载
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
        this.userDetailsService = userDetailsService;
    }

    /**
     * 提供密码编码器，用于密码加密
     *
     * @return BCryptPasswordEncoder实例，用于加密密码
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 配置身份验证管理器
     *
     * @param config 身份验证配置
     * @return AuthenticationManager实例，用于处理身份验证请求
     * @throws Exception 如果配置过程中发生错误
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    /**
     * 配置Spring Security过滤器链
     *
     * @param http HttpSecurity实例，用于配置HTTP安全设置
     * @return SecurityFilterChain实例，表示配置好的安全过滤器链
     * @throws Exception 如果配置过程中发生错误
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable()) // 禁用CSRF保护，适用于无状态认证
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 设置会话管理策略为无状态
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/auth/login").permitAll() // 允许所有用户访问登录接口
                        .anyRequest().authenticated()) // 其他所有请求都需要身份验证
                .authenticationProvider(authenticationProvider()) // 设置身份验证提供者
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); // 在用户名密码身份验证过滤器之前添加JWT身份验证过滤器

        return http.build();
    }

    /**
     * 配置Dao身份验证提供者
     *
     * @return DaoAuthenticationProvider实例，用于处理身份验证请求
     */
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService); // 设置用户详细服务
        authProvider.setPasswordEncoder(passwordEncoder()); // 设置密码编码器
        return authProvider;
    }
}
